<?php
/**
 * BaseTextDao.class.php
 * 
 * (C) 2009, tetsuya.odaka(EzoGP).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* 
 * textファイル操作のためのDao
 * 
 * 
 * author；	t.odaka
 * date ;	2009/5/3
 * 
 */

class BaseTextDao {
	/*
	* プロパティー 
	*/
	// ファイル名（パス付き）
	var $FileName;
	var $LockFileName;
	
    /* 
	 * デフォルトのコンストラクタ 
	 */
	function __construct() {
	}

	/* 
	 * Getter 
	 */
	function getFileName(){return $this->FileName;}
	function getLockFileName(){return $this->LockFileName;}
	
	/* 
	 * Setter 
	 */
	function setFileName($_str){
		$this->FileName = $_str;
		// デフォルトのロックファイル
		$this->LockFileName = $this->FileName.'.lck';
		return;
	}
	
	// 特別にロックファイルを設定した場合
	function setLockFileName($_str){
		if($_str){
			$this->LockFileName = $_str;
		}
		return;
	}
	
	/*
 	* getLock
 	*   this->FileNameのロックファイルを作成します。
 	* 	ファイルロックが、タイムアウト値までに取得できなければ、失敗となります。
	*   パラメータ
	* 	$_tout	:   タイムアウト値（milisec）
 	*  	戻り値	:	ロックファイルを生成できたらtrue、失敗したらfail。
 	*/
	function getLock($_tout){
		require("../Myznala/debugLog.php");
	
		if(!is_numeric($_tout)) return null;
		if($_tout < 0) return null;
		
//		$myDebugLog->debug('$_tout: '.$_tout); // Debugログ
		
		// タイムアウトするループ回数
		$_eol = round($_tout/5000);
//		$myDebugLog->debug('$_eol: '.$_eol); // Debugログ
		
		// lockファイル名
		$_lckfn = $this->LockFileName;
//		$myDebugLog->debug('$_lckfn: '.$_lckfn); // Debugログ
		
		// ループカウンタ
		$_lcnt = 0;
		
		while($_lcnt < $_eol){
//			$myDebugLog->debug('$_lcnt: '.$_lcnt.' : '.microtime()); // Debugログ
			if(!file_exists($_lckfn)){
				// ロックファイルの生成
				if(touch($_lckfn)){
					// ファイルオープン
//					$myDebugLog->debug('create lock file.'); // Debugログ
					return true;
				}else{
					return false;
				}
			}
			// 0.005 秒待つ
			usleep(5000);
			$_lcnt++;
		}
		
		return false;
	}

	
	/*
 	* releaseLock
 	*   ロックファイルを削除して、ファイルロックを解除します
 	* 	ファイルロックが、1秒間解除できなければ、失敗となります（無限ループ防止）。
	* 	パラメータ
	* 	戻り値	:   ロックファイルを削除したらtrue、失敗したらfalse。
 	*/
	function releaseLock(){
		require("../Myznala/debugLog.php");
		
		// lockファイル名
		$_lckfn = $this->LockFileName;
	
		// ループカウンタ
		$_lcnt = 0;
		while($_lcnt < 20){
			if(file_exists($_lckfn)){
				// ロックファイルの削除
				if(unlink($_lckfn)){
//				$myDebugLog->debug('remove lock file.'); // Debugログ
				return true;
				}
				return false;
			}
			// 0.05 秒待つ
			usleep(50000);
			$_lcnt++;
		}
		return false;
	}
	
	/*
 	* fileLockOpen
 	*   this->FileNameをファイルロックし、ファイルポインタを返却します。
 	* 	ファイルロックが、タイムアウト値までに取得できなければ、失敗となります。
	*   パラメータ
	* 	$_opt	:   'r','r+','a','w',...
	* 	$_tout	:   タイムアウト値（milisec）
 	*  	戻り値	:	ロックファイルを生成し、ファイルをオープンできたらファイルポインタ、失敗したらnull。
 	*/
	function fileLockOpen($_opt, $_tout){
		require("../Myznala/debugLog.php");
	
		// ファイルロックの獲得
		if($this->getLock($_tout)){
		// ファイルオープン
			$_fp = fopen($this->FileName, $_opt);
			if(!$_fp) return null;
		}else{
			return null;
		}
		
		return $_fp;
	}
	
	/*
 	* fileOpen
 	*   this->FileNameのファイルポインタを取得します
 	*   ファイルが、a, r+の場合にはファイルロックをして、ファイルを開きます。
	* 	パラメータ
	* 	$_opt	:   'r','r+','a','w'
 	*  	戻り値	:	正常にファイルをオープンできたらファイルポインタ、失敗したらnull。
 	*/
	function fileOpen($_opt){

		if($_opt == 'r+' || $_opt == 'a'){
			// ファイルオープン
			$_fp = $this->fileLockOpen(1000000);
			if(!$_fp) return null;
		}else{
			// ファイルオープン
			$_fp = fopen($this->FileName, $_opt);
			if(!$_fp) return null;
		}
		return $_fp;
	}
	
	/*
 	* fileLockClose
 	*   ファイルロックを解除して、ファイルをクローズします
 	* 	ファイルロックが、1秒間解除できなければ、失敗となります（無限ループ防止）。
	* 	パラメータ
	*   $_fp	:	ファイルポインタ
	* 	戻り値	:   ロックファイルを削除し、ファイルをクローズしたらtrue、失敗したらfalse。
 	*/
	function fileLockClose($_fp){
		// ロックファイルの削除
		if($this->releaseLock()){
			// ファイルクローズ
			if(fclose($_fp)) return true;
			return false;
		}else{
			return false;
		}
	}
	
	/*
 	* fileClose
 	*   ファイルポインタを受け取ってファイルをクローズします。
 	*   ファイルが、a, r+の場合にはファイルロック解除して、ファイルを閉じます。
	*   パラメータ
	*   $_fp	:	ファイルポインタ
	* 	$_opt	:   'r','r+','a','w'
	*   戻り値	:	ファイルが正常にクローズできたらtrue、失敗したらfalse。
 	*/
	function fileClose($_fp, $_opt){
		if($_opt == 'r+' || $_opt == 'a'){
			// ファイルクローズ
			if(!$this->fileLockClose($_fp)) return false;
		}
		// ファイルクローズ
		if(!fclose($_fp)) return false;
		return true;
	}
}
?>
